Skip to content

API Keys #426

Closed
hrishikesh-p wants to merge 14 commits intomainfrom
feature/opaque-tokens-docs
Closed

API Keys #426
hrishikesh-p wants to merge 14 commits intomainfrom
feature/opaque-tokens-docs

Conversation

@hrishikesh-p
Copy link
Collaborator

@hrishikesh-p hrishikesh-p commented Feb 11, 2026

  • docs: add opaque API tokens documentation
  • docs: improve opaque tokens page per writing standards review
  • docs: rename opaque tokens to API keys with tone shift and structural improvements
  • docs: use specific error types in API keys validate token examples
  • docs: adjust API keys tone to match sibling articles and reorder sidebar

Summary by CodeRabbit

  • Documentation

    • Added a comprehensive API keys guide with multi-language examples for creating, validating, listing, and revoking keys; includes middleware patterns and security best practices.
    • Reworked the API auth quickstart to emphasize OAuth 2.0 and the client credentials flow.
    • Removed the previous "Verify API client scopes" guide.
  • Navigation

    • Updated sidebar to point to the new API keys doc and added a redirect from the old scopes path.
  • Chores

    • Added a contributor note advising not to include Co-Authored-By lines in commit messages.

hrishikesh-p and others added 6 commits February 11, 2026 16:37
Add comprehensive documentation for opaque API tokens under
"Add auth to your APIs" section. Covers create, validate, list,
and invalidate operations with code examples in all 4 SDKs
(Node.js, Python, Go, Java). Includes middleware patterns for
protecting API endpoints and best practices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tags, error handling, security comments, collapse for init blocks,
Python tuple explanation, and closing next-steps section.
… improvements

- Rename opaque-tokens.mdx to api-keys.mdx, update sidebar config
- Rewrite intro with Scalekit recommendation tone
- Add D2 sequence diagram showing API key lifecycle flow
- Split create token into org-scoped and user-scoped subsections
- Add validate subsections for roles/externalOrgId and custom metadata
- Reorder invalidate examples (API key first, tokenId second)
- Remove framework titles from generic code examples
- Replace log.Fatalf with log.Printf in Go examples
- Update all prose references from opaque tokens to API keys
Update all validate token examples to catch SDK-specific exceptions
(ScalekitValidateTokenFailureException, ErrTokenValidationFailed,
TokenInvalidException) instead of generic Error/Exception, and add
bullet-pointed intro section.
Rewrite prose sections with a warmer, more conversational tone matching
the api-auth-quickstart and scopes articles. Move API keys to last
position under "Add auth to your APIs" in the sidebar.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e056ac and e2fb272.

📒 Files selected for processing (1)
  • src/content/docs/authenticate/m2m/api-keys.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/content/docs/authenticate/m2m/api-keys.mdx

📝 Walkthrough

Walkthrough

Added a new comprehensive API-keys doc, removed the old M2M scopes guide, updated OAuth2 quickstart and sidebar/redirects to point to the new content, and added a Git commit guideline in CLAUDE.md. No public code-level APIs changed. (50 words)

Changes

Cohort / File(s) Summary
Contributor guidance
CLAUDE.md
Added a "Git Commits" subsection instructing contributors not to include Co-Authored-By lines in commit messages.
Sidebar configuration
src/configs/sidebar.config.ts
Replaced sidebar entry guides/m2m/scopes with authenticate/m2m/api-keys under the "Add auth to your APIs" group.
New API keys documentation
src/content/docs/authenticate/m2m/api-keys.mdx
Added a large new API keys guide covering overview, SDK init, token lifecycle (create/validate/list/invalidate), token semantics, multi-language middleware/examples (Node/Python/Go/Java), pagination/filtering, revocation, best practices, and diagrams. Review multi-language samples and security/storage guidance.
Redirects
src/configs/redirects.config.ts
Added redirect: /guides/m2m/scopes//authenticate/m2m/api-auth-quickstart/.
OAuth2 quickstart updates
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
Reframed toward OAuth2/client_credentials, updated title/sidebar label, expanded client registration, scopes registration/verification, and updated multi-language examples and scope-verification middleware samples.
Removed scopes guide
src/content/docs/guides/m2m/scopes.mdx
Deleted the previous "Verify API client scopes" guide (removed multi-language examples and validation guidance).
Navigation frontmatter updates
src/content/docs/guides/m2m/api-auth-m2m-clients.mdx
Removed prev/next frontmatter links referencing the deleted scopes page and an adjacent next link; verify navigation chain and broken links.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ravibits
  • amitash1912
  • saif-at-scalekit

Poem

🐇
I hopped through docs and found a key,
Swapped an old page out and set the sidebar free,
Commit notes tidy — no co-author line,
Tokens snug in examples, all samples align,
A little hop, a doc delight — hooray for devs like me!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title "API Keys" is vague and generic. While it relates to the main content addition, it doesn't clearly indicate the specific change—adding new documentation for API keys in M2M authentication. Consider a more descriptive title such as "Add API Keys documentation for M2M authentication" or "Introduce API Keys section for M2M auth" to better convey the primary change.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/opaque-tokens-docs

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link

netlify bot commented Feb 11, 2026

Deploy Preview for scalekit-starlight ready!

Name Link
🔨 Latest commit e2fb272
🔍 Latest deploy log https://app.netlify.com/projects/scalekit-starlight/deploys/699c3000ba6f810008c8f371
😎 Deploy Preview https://deploy-preview-426--scalekit-starlight.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 898-900: The "Set expiry for time-limited access" Card references
an `expiry` parameter but the "Create a token" examples don't show it; update
the create-token examples in this doc to demonstrate supplying an `expiry` value
(or add a short note linking to the API reference) so readers see how to set
time-limited keys—modify the "Create a token" code blocks near the Card titled
"Set expiry for time-limited access" to include an `expiry` field (and a brief
inline comment) or add a one-line callout that points to the API reference for
`expiry`.
- Line 23: Summary: Hyphenate the compound adjective "server side validation" to
"server-side validation". Fix: locate the sentence containing "server side
validation" in the API keys description (the sentence that reads "API Keys can
be validated via APIs with Scalekit and after server side validation...") and
replace "server side validation" with "server-side validation" so the compound
adjective is correctly hyphenated.
- Around line 179-191: The Java example for creating an organization-scoped
token omits the description parameter; update the call to
scalekitClient.tokens().create(organizationId) to pass a description string
(matching how Node/Python/Go do) so the CreateTokenResponse creation includes
the description field; locate the example using CreateTokenResponse and
scalekitClient.tokens().create(...) and add the description argument
consistently with the user-scoped token example.
🧹 Nitpick comments (1)
src/content/docs/authenticate/m2m/api-keys.mdx (1)

383-398: Missing import for ScalekitValidateTokenFailureException.

The exception is used in the catch block but the import statement is not shown in this code example. For consistency with line 304 and to ensure the example is complete, consider adding the import.

📝 Suggested fix
 ```javascript
+import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node';
+
 try {
   const result = await scalekit.token.validateToken(opaqueToken);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c00fc0 and 7403a23.

⛔ Files ignored due to path filters (1)
  • public/d2/docs/authenticate/m2m/api-keys-0.svg is excluded by !**/*.svg
📒 Files selected for processing (3)
  • CLAUDE.md
  • src/configs/sidebar.config.ts
  • src/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{md,mdx}: All code examples must include implementations in all 4 languages: Node.js, Python, Go, and Java
Include security comments in code examples explaining security threats and implications
Code examples must demonstrate both success and error paths
Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array
Use second person ('you', 'your application') for writing voice in documentation
Use present tense for descriptions and imperative mood for instructions in documentation

**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and...

Files:

  • CLAUDE.md
  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)

**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'

Files:

  • CLAUDE.md
  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.mdx

📄 CodeRabbit inference engine (.cursorrules)

**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component: 1. ## Title with all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{js,ts,py,go,java,tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

SDK variable names must follow language-specific conventions: Node.js uses scalekit, Python uses scalekit_client, Go uses scalekitClient, Java uses scalekitClient

Files:

  • src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code

Files:

  • src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements

Files:

  • src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases

Files:

  • src/configs/sidebar.config.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
📚 Learning: 2026-01-13T12:47:04.673Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T12:47:04.673Z
Learning: Applies to **/*.{js,ts,py,go,java,tsx,jsx} : SDK variable names must follow language-specific conventions: Node.js uses `scalekit`, Python uses `scalekit_client`, Go uses `scalekitClient`, Java uses `scalekitClient`

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.

Applied to files:

  • CLAUDE.md
  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
  • src/configs/sidebar.config.ts
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.

Applied to files:

  • src/configs/sidebar.config.ts
🪛 LanguageTool
src/content/docs/authenticate/m2m/api-keys.mdx

[grammar] ~23-~23: Use a hyphen to join words.
Context: ... via APIs with Scalekit and after server side validation, the claims are sent whe...

(QB_NEW_EN_HYPHEN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules - scalekit-starlight
  • GitHub Check: Header rules - scalekit-starlight
  • GitHub Check: Pages changed - scalekit-starlight
🔇 Additional comments (4)
CLAUDE.md (1)

36-38: LGTM!

The addition of the Git Commits reminder is clear and follows the existing structure of the Key Reminders section.

src/configs/sidebar.config.ts (1)

71-71: LGTM!

The new sidebar entry is correctly placed within the "Add auth to your APIs" section, logically following the API auth quickstart and scopes documentation.

src/content/docs/authenticate/m2m/api-keys.mdx (2)

718-888: Well-structured middleware examples with comprehensive security comments.

The middleware patterns are consistently implemented across all four languages, with clear security comments explaining the rationale for each check. The examples are complete and demonstrate both authentication and authorization context handling.


1-911: Comprehensive and well-structured API keys documentation.

This guide thoroughly covers the API keys lifecycle with consistent multi-language examples, appropriate security comments, and clear explanations. The D2 sequence diagram, middleware patterns, and best practices section add significant value for developers implementing API key authentication.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +179 to +191
```java
try {
CreateTokenResponse response = scalekitClient.tokens().create(organizationId);

// Store securely — this value cannot be retrieved again after creation
String opaqueToken = response.getToken();
// Stable identifier for management operations (format: apit_xxxxx)
String tokenId = response.getTokenId();
} catch (Exception e) {
System.err.println("Failed to create token: " + e.getMessage());
}
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's check the file structure and context around the disputed code
fd "api-keys.mdx" --type f

Repository: scalekit-inc/developer-docs

Length of output: 117


🏁 Script executed:

# Check the exact content of the file around lines 179-191 and the surrounding examples
cat -n src/content/docs/authenticate/m2m/api-keys.mdx | sed -n '150,220p'

Repository: scalekit-inc/developer-docs

Length of output: 2467


🏁 Script executed:

# Search for Java SDK implementation or type definitions that might show the create method signature
find . -type f -name "*.java" -o -name "*.ts" -o -name "*.js" -o -name "*.json" | head -20

Repository: scalekit-inc/developer-docs

Length of output: 693


🏁 Script executed:

# Look for SDK documentation or type definitions within the repo
fd -e ts -e d.ts | xargs rg "create.*organizationId" -A 3 -B 1 2>/dev/null | head -50

Repository: scalekit-inc/developer-docs

Length of output: 53


🏁 Script executed:

# Get earlier lines to see the Node.js and Python examples
cat -n src/content/docs/authenticate/m2m/api-keys.mdx | sed -n '120,160p'

Repository: scalekit-inc/developer-docs

Length of output: 1445


🏁 Script executed:

# Search for Java SDK type definitions or examples in the codebase
find . -type f \( -name "*.java" -o -name "*.ts" -o -name "*.d.ts" \) | xargs rg "CreateTokenResponse|tokens.*create" 2>/dev/null | head -30

Repository: scalekit-inc/developer-docs

Length of output: 53


🏁 Script executed:

# Check if there's SDK documentation or OpenAPI spec that describes the Java SDK
fd -e json -e yaml -e yml | xargs rg "CreateToken|create.*token" 2>/dev/null | head -20

Repository: scalekit-inc/developer-docs

Length of output: 950


🏁 Script executed:

# Search for any references to the Java SDK's create method parameters
rg "scalekitClient.*tokens.*create" --type mdx -A 5 -B 5

Repository: scalekit-inc/developer-docs

Length of output: 98


🏁 Script executed:

# Look for the Java SDK create token method in the OpenAPI spec
rg "CreateToken|create.*token" public/api/scalekit.scalar.json -A 10 | head -100

Repository: scalekit-inc/developer-docs

Length of output: 2803


🏁 Script executed:

# Check if there's a postman collection with example requests
rg "create.*token\|CreateToken" public/api/scalekit.postman_collection.json -A 5 -B 2 | head -50

Repository: scalekit-inc/developer-docs

Length of output: 53


🏁 Script executed:

# Search the documentation for any other Java examples that show the create method with parameters
cat src/content/docs/authenticate/m2m/api-keys.mdx | grep -A 10 "java" | grep -A 10 "create"

Repository: scalekit-inc/developer-docs

Length of output: 1512


Java example omits description parameter inconsistently with other language examples.

The Node.js, Python, and Go examples all pass a description parameter when creating organization-scoped tokens, but the Java example doesn't include it. The Java SDK clearly supports this parameter (as shown in the user-scoped token example below), making this an inconsistency that should be addressed for clarity.

📝 Suggested fix
 try {
-    CreateTokenResponse response = scalekitClient.tokens().create(organizationId);
+    CreateTokenResponse response = scalekitClient.tokens().create(
+        organizationId, null, null, null, "CI/CD pipeline token"
+    );

     // Store securely — this value cannot be retrieved again after creation
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 179 - 191, The
Java example for creating an organization-scoped token omits the description
parameter; update the call to scalekitClient.tokens().create(organizationId) to
pass a description string (matching how Node/Python/Go do) so the
CreateTokenResponse creation includes the description field; locate the example
using CreateTokenResponse and scalekitClient.tokens().create(...) and add the
description argument consistently with the user-scoped token example.

Comment on lines +898 to +900
<Card title="Set expiry for time-limited access">
Use the `expiry` parameter for keys that should automatically become invalid after a set period. This limits the blast radius if a key is compromised.
</Card>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Best practice references undocumented expiry parameter.

The "Set expiry for time-limited access" card mentions using the expiry parameter, but this parameter is not demonstrated in the "Create a token" code examples. Consider adding an example showing how to set token expiry, or clarifying that this feature exists and linking to API reference.

Would you like me to draft an example showing how to use the expiry parameter in the create token examples?

🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 898 - 900, The
"Set expiry for time-limited access" Card references an `expiry` parameter but
the "Create a token" examples don't show it; update the create-token examples in
this doc to demonstrate supplying an `expiry` value (or add a short note linking
to the API reference) so readers see how to set time-limited keys—modify the
"Create a token" code blocks near the Card titled "Set expiry for time-limited
access" to include an `expiry` field (and a brief inline comment) or add a
one-line callout that points to the API reference for `expiry`.

Copy link
Collaborator

@saif-at-scalekit saif-at-scalekit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@saif-at-scalekit
Copy link
Collaborator

Do not merge yet, I will come back to do a few updates.

…nology and enhance clarity

- Changed the title from "Add auth to your APIs" to "Add OAuth2.0 to your APIs" for specificity.
- Revised introductory content to clarify the role of APIs and the importance of OAuth 2.0 for client credentials authentication.
- Improved the description of the API client registration process, emphasizing customer interaction and Scalekit integration.
- Added details on API client scopes and their validation, enhancing security context.
- Included collapsible sections for sample responses to improve readability and organization.

This update aligns the documentation with current standards and enhances user understanding of OAuth 2.0 integration.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx (3)

2-23: ⚠️ Potential issue | 🟠 Major

Add required frontmatter metadata and make the BrowseCentral label action‑oriented.

This page has multiple sections but lacks tableOfContents, and there’s no tags array. Also, the BrowseCentral label should start with a verb, and the title should use “OAuth 2.0”.

✏️ Suggested frontmatter update
-title: Add OAuth2.0 to your APIs
+title: Add OAuth 2.0 to your APIs
 description: "Secure your APIs in minutes with OAuth 2.0 client credentials, scoped access, and JWT validation using Scalekit"
 browseCentral:
-  label: "API authentication with M2M OAuth"
+  label: "Authenticate APIs with M2M OAuth"
   filterType: ["tutorial"]
   category: ["Auth modules"]
   icon: book
+tags: [oauth2, m2m, api-auth, client-credentials]
+tableOfContents: true
 sidebar:
   label: "Add OAuth 2.0"

As per coding guidelines: “Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array” and “Use tableOfContents property in frontmatter when content has multiple sections.” Also: “BrowseCentral labels should be action-oriented - start with verbs when possible.”


28-43: ⚠️ Potential issue | 🟡 Minor

Fix grammar and typos in the introduction and diagram.

Several small errors reduce clarity (its/it’s, “OAuth 2.0-based”, “Here’s how it works”, and “credentials”).

✏️ Suggested edits
-APIs are a way to let your customers, partners, and external systems interact with your application and it's data. It requires authentication to ensure only authorized clients can consume your APIs. Scalekit provides a way to add OAuth2.0 based client credentials authentication to your API endpoints.
+APIs are a way to let your customers, partners, and external systems interact with your application and its data. It requires authentication to ensure only authorized clients can consume your APIs. Scalekit provides a way to add OAuth 2.0-based client credentials authentication to your API endpoints.

-In should here's how it would work:
+Here's how it works:
-User -> API Client: 4. Saves the API credetials
+User -> API Client: 4. Saves the API credentials

74-232: ⚠️ Potential issue | 🟠 Major

Add Go/Java examples and use the standard tech‑stack tab values.

Step 2 only shows cURL + Python, and value="curl" doesn’t match the required tech‑stack keys. Please add Node.js/Go/Java examples (keep cURL as optional) and use node, python, go, java values.

As per coding guidelines: “Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps components” and “Use consistent Tab labels for multi-language examples: 'Node.js', 'Python', 'Go', 'Java' with TabItem values 'node', 'python'/'py', 'go'/'golang', 'java'.”

🤖 Fix all issues with AI agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx`:
- Around line 393-418: The JSON sample contains a realistic-looking secret in
the "plain_secret" field that triggered secret scanning; replace that value with
a clearly fake placeholder (e.g., "PLAINTEXT_SECRET_PLACEHOLDER") and scan the
rest of this MDX file for any other realistic-looking tokens (e.g.,
secret_suffix, client_id, sks_* values) and replace them with generic
placeholders to avoid accidental reuse or scanning alerts; update the sample
JSON block shown in api-auth-quickstart.mdx and any other sample blocks in the
same file to use non-sensitive placeholders consistently.
- Around line 367-522: Fix the typo "or example" to "For example," and add Go
and Java TabItem examples alongside the existing curl, node, and python TabItem
blocks (use unique identifiers like Tabs(syncKey="tech-stack") and TabItem
value="go"/"java"); ensure the Tabs component is indented with 3 spaces inside
its parent Steps, each TabItem is at the same indentation level as its Tabs
parent, and code blocks inside each TabItem are properly indented to match the
other examples so the four-language requirement (Node.js, Python, Go, Java) and
indentation rules are satisfied.

In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 551-634: Update the three language examples to include explicit
success and error handling around the list calls (handle promise
rejection/exception and check returned error values) and replace redundant
comments with intent-focused ones; specifically wrap scalekit.token.listTokens
(JS), scalekit_client.tokens.list_tokens (Python), and
scalekitClient.Token().ListTokens (Go) calls with try/catch / if err / exception
handling and log or surface errors, check for nil/empty responses before
iterating (response, response[0], response.Tokens), and change comments to
explain why pagination or filtering is used (e.g., "iterate pages to fetch all
tokens" or "filter to tokens owned by a specific user") instead of restating the
code.
- Around line 21-23: Update the opening paragraph to fix grammar and
consistency: change "Scalekit API keys gives you" to "Scalekit API keys give
you", hyphenate "organization- or user-level", use consistent lowercase "API
keys" and hyphenate "client-side", and rework the second sentence to read
something like "Unlike JWT-based M2M authentication, API keys do not carry
embedded claims and cannot be validated on the client side; they must be
validated via Scalekit APIs, which then provide claims after server-side
validation." Ensure these edits are applied to the paragraph containing the
phrases "Scalekit API keys", "JWT-based M2M authentication", "client side", and
"API Keys can be validated via APIs with Scalekit".
- Around line 725-875: Add the required security comment string "// Security:
ALWAYS verify requests are from Scalekit before processing" immediately adjacent
to the token validation call in each example: in the Express middleware function
authenticateToken (where scalekit.token.validateToken is called), in the Flask
decorator authenticate_token (where scalekit_client.tokens.validate_token is
called), in the Gin handler AuthenticateToken (around
scalekitClient.Token().ValidateToken), and in the Spring Boot filter
TokenAuthFilter.doFilterInternal (around scalekitClient.tokens().validate);
place the comment right above or on the same line as the validation call so it
is clearly associated with the security check.
- Around line 1-6: Update the MDX frontmatter to add tableOfContents: true and
change the sidebar label to sentence case; specifically, in the existing
frontmatter where title: "API keys", description, sidebar: label: "Add API
Keys", and tags are defined, insert tableOfContents: true and change sidebar:
label to "Add API keys" so the page renders a TOC and the sidebar uses sentence
case.
🧹 Nitpick comments (1)
src/configs/redirects.config.ts (1)

258-260: Avoid a redirect chain for /m2m/scopes.

/m2m/scopes currently hops through /guides/m2m/scopes/ before reaching the new destination. Point it directly to the final URL to reduce one redirect.

♻️ Suggested change
-  '/m2m/scopes': '/guides/m2m/scopes/',
+  '/m2m/scopes': '/authenticate/m2m/api-auth-quickstart/',
   '/guides/m2m/scopes/': '/authenticate/m2m/api-auth-quickstart/',
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7403a23 and ea6e0d8.

📒 Files selected for processing (6)
  • src/configs/redirects.config.ts
  • src/configs/sidebar.config.ts
  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
  • src/content/docs/guides/m2m/api-auth-m2m-clients.mdx
  • src/content/docs/guides/m2m/scopes.mdx
💤 Files with no reviewable changes (2)
  • src/content/docs/guides/m2m/api-auth-m2m-clients.mdx
  • src/content/docs/guides/m2m/scopes.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/configs/sidebar.config.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,py,go,java,tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

SDK variable names must follow language-specific conventions: Node.js uses scalekit, Python uses scalekit_client, Go uses scalekitClient, Java uses scalekitClient

Files:

  • src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code

Files:

  • src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements

Files:

  • src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)

Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases

Files:

  • src/configs/redirects.config.ts
**/*.mdx

📄 CodeRabbit inference engine (.cursorrules)

**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component: 1. ## Title with all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...

Files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{md,mdx}: All code examples must include implementations in all 4 languages: Node.js, Python, Go, and Java
Include security comments in code examples explaining security threats and implications
Code examples must demonstrate both success and error paths
Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array
Use second person ('you', 'your application') for writing voice in documentation
Use present tense for descriptions and imperative mood for instructions in documentation

**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and...

Files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)

**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'

Files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (10)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.mdx : Use Tabs/TabItem components for multi-language or multi-framework examples in MDX documentation

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Tabs components within Steps must be indented with 3 spaces, TabItem at same level as parent Tabs, code blocks properly indented within TabItem

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.

Applied to files:

  • src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
🪛 Gitleaks (8.30.0)
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx

[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 LanguageTool
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx

[grammar] ~28-~28: Use a hyphen to join words.
Context: ... Scalekit provides a way to add OAuth2.0 based client credentials authentication ...

(QB_NEW_EN_HYPHEN)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +367 to +522
5. ## Register API client's scopes <Badge text="Optional" />

Scopes are embedded in the access token and validated server-side using the Scalekit SDK. This ensures that API clients only access resources they're authorized for, adding an extra layer of security.

or example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`.

<Tabs syncKey="tech-stack">
<TabItem value="curl" label="cURL">

```bash title="Register an API client with specific scopes" wrap
curl -L 'https://<SCALEKIT_ENVIRONMENT_URL>/api/v1/organizations/<ORGANIZATION_ID>/clients' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <SCALEKIT_ACCESS_TOKEN>' \
-d '{
"name": "GitHub Actions Deployment Service",
"description": "Service account for GitHub Actions to deploy applications to production",
"scopes": [
"deploy:applications",
"read:deployments"
],
"expiry": 3600
}'
```
<details>
<summary>Sample response</summary>

```json title="Sample response" showLineNumbers=false
{
"client": {
"client_id": "m2morg_68315758685323697",
"secrets": [
{
"id": "sks_68315758802764209",
"create_time": "2025-04-16T06:56:05.360Z",
"update_time": "2025-04-16T06:56:05.367190455Z",
"secret_suffix": "UZ0X",
"status": "ACTIVE",
"last_used_time": "2025-04-16T06:56:05.360Z"
}
],
"name": "GitHub Actions Deployment Service",
"description": "Service account for GitHub Actions to deploy applications to production",
"organization_id": "org_59615193906282635",
"create_time": "2025-04-16T06:56:05.290Z",
"update_time": "2025-04-16T06:56:05.292145150Z",
"scopes": [
"deploy:applications",
"read:deployments"
]
},
"plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X"
}
```
</details>
</TabItem>
<TabItem value="node" label="Node.js">

```javascript title="Register an API client with specific scopes"
// Use case: Your customer requests API access for their deployment automation.
// You register an API client app with the appropriate scopes.
import { ScalekitClient } from '@scalekit-sdk/node';

// Initialize Scalekit client (see installation guide for setup)
const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);

async function createAPIClient() {
try {
// Define API client details with scopes your customer's app needs
const clientDetails = {
name: 'GitHub Actions Deployment Service',
description: 'Service account for GitHub Actions to deploy applications to production',
scopes: ['deploy:applications', 'read:deployments'],
expiry: 3600, // Token expiry in seconds
};

// API call to register the client
const response = await scalekit.m2m.createClient({
organizationId: process.env.SCALEKIT_ORGANIZATION_ID,
client: clientDetails,
});

// Response contains client details and the plain_secret (only returned once)
const clientId = response.client.client_id;
const plainSecret = response.plain_secret;

// Provide these credentials to your customer securely
console.log('Created API client:', clientId);
} catch (error) {
console.error('Error creating API client:', error);
}
}

createAPIClient();
```

</TabItem>
<TabItem value="python" label="Python">

```python title="Register an API client with specific scopes"
# Use case: Your customer requests API access for their deployment automation.
# You register an API client app with the appropriate scopes.
import os
from scalekit import ScalekitClient

# Initialize Scalekit client (see installation guide for setup)
scalekit_client = ScalekitClient(
env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET")
)

try:
# Define API client details with scopes your customer's app needs
from scalekit.v1.clients.clients_pb2 import OrganizationClient

client_details = OrganizationClient(
name="GitHub Actions Deployment Service",
description="Service account for GitHub Actions to deploy applications to production",
scopes=["deploy:applications", "read:deployments"],
expiry=3600 # Token expiry in seconds
)

# API call to register the client
response = scalekit_client.m2m_client.create_organization_client(
organization_id=os.getenv("SCALEKIT_ORGANIZATION_ID"),
m2m_client=client_details
)

# Response contains client details and the plain_secret (only returned once)
client_id = response.client.client_id
plain_secret = response.plain_secret

# Provide these credentials to your customer securely
print("Created API client:", client_id)

except Exception as e:
print("Error creating API client:", e)
```

</TabItem>
</Tabs>

The API returns a JSON object with two key parts:
- `client.client_id` - The client identifier
- `plain_secret` - The client secret (only returned once, never stored by Scalekit)

Provide both values to your customer securely. Your customer will use these credentials in their application to authenticate with your API. The `plain_secret` is never shown again after creation.

<Aside type="tip" title="Additional parameters">
You can also include `custom_claims` (key-value metadata) and `audience` (target API endpoints) when registering API clients. See the [quickstart guide](/authenticate/m2m/api-auth-quickstart) for examples.
</Aside>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix typo and add Go/Java tabs for the scopes section.

This step has a typo (“or example”) and only cURL/Node/Python. Add Go/Java to meet the 4‑language requirement, and ensure Tabs/TabItem indentation stays consistent within <Steps>.

✏️ Typo fix
-   or example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`.
+   For example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`.

As per coding guidelines: “Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps components.” Based on learnings: “Tabs components within Steps must be indented with 3 spaces, TabItem at same level as parent Tabs, code blocks properly indented within TabItem.”

🧰 Tools
🪛 Gitleaks (8.30.0)

[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx` around lines 367 -
522, Fix the typo "or example" to "For example," and add Go and Java TabItem
examples alongside the existing curl, node, and python TabItem blocks (use
unique identifiers like Tabs(syncKey="tech-stack") and TabItem
value="go"/"java"); ensure the Tabs component is indented with 3 spaces inside
its parent Steps, each TabItem is at the same indentation level as its Tabs
parent, and code blocks inside each TabItem are properly indented to match the
other examples so the four-language requirement (Node.js, Python, Go, Java) and
indentation rules are satisfied.

Comment on lines +393 to +418
```json title="Sample response" showLineNumbers=false
{
"client": {
"client_id": "m2morg_68315758685323697",
"secrets": [
{
"id": "sks_68315758802764209",
"create_time": "2025-04-16T06:56:05.360Z",
"update_time": "2025-04-16T06:56:05.367190455Z",
"secret_suffix": "UZ0X",
"status": "ACTIVE",
"last_used_time": "2025-04-16T06:56:05.360Z"
}
],
"name": "GitHub Actions Deployment Service",
"description": "Service account for GitHub Actions to deploy applications to production",
"organization_id": "org_59615193906282635",
"create_time": "2025-04-16T06:56:05.290Z",
"update_time": "2025-04-16T06:56:05.292145150Z",
"scopes": [
"deploy:applications",
"read:deployments"
]
},
"plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace sample secrets with placeholders.

The sample plain_secret value looks like a real token and triggered secret scanning. Use a placeholder (and update other samples in this file) to avoid accidental reuse.

🔒 Suggested redaction
-       "plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X"
+       "plain_secret": "<PLAIN_SECRET>"
🧰 Tools
🪛 Gitleaks (8.30.0)

[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx` around lines 393 -
418, The JSON sample contains a realistic-looking secret in the "plain_secret"
field that triggered secret scanning; replace that value with a clearly fake
placeholder (e.g., "PLAINTEXT_SECRET_PLACEHOLDER") and scan the rest of this MDX
file for any other realistic-looking tokens (e.g., secret_suffix, client_id,
sks_* values) and replace them with generic placeholders to avoid accidental
reuse or scanning alerts; update the sample JSON block shown in
api-auth-quickstart.mdx and any other sample blocks in the same file to use
non-sensitive placeholders consistently.

Comment on lines +1 to +6
---
title: API keys
description: "Issue long-lived, revocable API keys scoped to organizations and users for programmatic access to your APIs"
sidebar:
label: "Add API Keys"
tags: [api-tokens, api-keys, m2m, authentication, bearer-tokens]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "authenticate/m2m" src/configs/sidebar.config.ts

Repository: scalekit-inc/developer-docs

Length of output: 165


🏁 Script executed:

sed -n '60,80p' src/configs/sidebar.config.ts

Repository: scalekit-inc/developer-docs

Length of output: 857


Add tableOfContents and fix sidebar label to sentence case.

The page has multiple sections and requires tableOfContents: true in frontmatter. The sidebar label should use sentence case: "Add API keys" (not "Add API Keys").

✏️ Suggested frontmatter update
 sidebar:
-  label: "Add API Keys"
+  label: "Add API keys"
+tableOfContents: true
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 1 - 6, Update
the MDX frontmatter to add tableOfContents: true and change the sidebar label to
sentence case; specifically, in the existing frontmatter where title: "API
keys", description, sidebar: label: "Add API Keys", and tags are defined, insert
tableOfContents: true and change sidebar: label to "Add API keys" so the page
renders a TOC and the sidebar uses sentence case.

Comment on lines +21 to +23
When your customers need to integrate with your APIs — whether for CI/CD pipelines, partner integrations, or internal tooling — they need a straightforward way to authenticate. Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs.

Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented. Revocation of API keys takes effect immediately with no expiry windows or propagation delays. Each key is scoped to an organization and optionally to a specific user, making it easy to build personal access tokens, per-user rate limiting, and audit trails.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tighten grammar and consistency in the opening paragraph.

A few fixes improve readability and consistency (“API keys give you…”, “organization- or user-level”, “API keys”, and “client-side”).

✏️ Suggested edits
-Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs.
+Scalekit API keys give you long-lived, revocable bearer credentials that can be issued to your customers for organization- or user-level access to your APIs.

-Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented.
+Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client-side. API keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API key is presented.
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 21 - 23, Update
the opening paragraph to fix grammar and consistency: change "Scalekit API keys
gives you" to "Scalekit API keys give you", hyphenate "organization- or
user-level", use consistent lowercase "API keys" and hyphenate "client-side",
and rework the second sentence to read something like "Unlike JWT-based M2M
authentication, API keys do not carry embedded claims and cannot be validated on
the client side; they must be validated via Scalekit APIs, which then provide
claims after server-side validation." Ensure these edits are applied to the
paragraph containing the phrases "Scalekit API keys", "JWT-based M2M
authentication", "client side", and "API Keys can be validated via APIs with
Scalekit".

Comment on lines +725 to +875
```javascript title="Express.js"
import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node';

async function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];

if (!token) {
// Reject requests without credentials to prevent unauthorized access
return res.status(401).json({ error: 'Missing authorization token' });
}

try {
// Server-side validation — Scalekit checks token status in real time
const result = await scalekit.token.validateToken(token);
// Attach token context to the request for downstream handlers
req.tokenInfo = result.tokenInfo;
next();
} catch (error) {
if (error instanceof ScalekitValidateTokenFailureException) {
// Revoked, expired, or malformed tokens are rejected immediately
return res.status(401).json({ error: 'Invalid or expired token' });
}
throw error;
}
}

// Apply to protected routes
app.get('/api/resources', authenticateToken, (req, res) => {
const orgId = req.tokenInfo.organizationId;
// Serve resources scoped to this organization
});
```

</TabItem>
<TabItem value="python" label="Python">

```python title="Flask"
from functools import wraps
from flask import request, jsonify, g
from scalekit import ScalekitValidateTokenFailureException

def authenticate_token(f):
@wraps(f)
def decorated(*args, **kwargs):
auth_header = request.headers.get("Authorization", "")
if not auth_header.startswith("Bearer "):
# Reject requests without credentials to prevent unauthorized access
return jsonify({"error": "Missing authorization token"}), 401

token = auth_header.split(" ")[1]

try:
# Server-side validation — Scalekit checks token status in real time
result = scalekit_client.tokens.validate_token(token=token)
# Attach token context for downstream handlers
g.token_info = result[0].token_info
except ScalekitValidateTokenFailureException:
# Revoked, expired, or malformed tokens are rejected immediately
return jsonify({"error": "Invalid or expired token"}), 401

return f(*args, **kwargs)
return decorated

# Apply to protected routes
@app.route("/api/resources")
@authenticate_token
def get_resources():
org_id = g.token_info.organization_id
# Serve resources scoped to this organization
```

</TabItem>
<TabItem value="go" label="Go">

```go title="Gin"
func AuthenticateToken(scalekitClient scalekit.Scalekit) gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if !strings.HasPrefix(authHeader, "Bearer ") {
// Reject requests without credentials to prevent unauthorized access
c.JSON(401, gin.H{"error": "Missing authorization token"})
c.Abort()
return
}

token := strings.TrimPrefix(authHeader, "Bearer ")

// Server-side validation — Scalekit checks token status in real time
result, err := scalekitClient.Token().ValidateToken(c.Request.Context(), token)
if errors.Is(err, scalekit.ErrTokenValidationFailed) {
// Revoked, expired, or malformed tokens are rejected immediately
c.JSON(401, gin.H{"error": "Invalid or expired token"})
c.Abort()
return
}

// Attach token context for downstream handlers
c.Set("tokenInfo", result.TokenInfo)
c.Next()
}
}

// Apply to protected routes
r.GET("/api/resources", AuthenticateToken(scalekitClient), func(c *gin.Context) {
tokenInfo := c.MustGet("tokenInfo").(*scalekit.TokenInfo)
orgId := tokenInfo.OrganizationId
// Serve resources scoped to this organization
})
```

</TabItem>
<TabItem value="java" label="Java">

```java title="Spring Boot"
import com.scalekit.exceptions.TokenInvalidException;

@Component
public class TokenAuthFilter extends OncePerRequestFilter {
private final ScalekitClient scalekitClient;

public TokenAuthFilter(ScalekitClient scalekitClient) {
this.scalekitClient = scalekitClient;
}

@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
// Reject requests without credentials to prevent unauthorized access
response.sendError(401, "Missing authorization token");
return;
}

String token = authHeader.substring(7);

try {
// Server-side validation — Scalekit checks token status in real time
ValidateTokenResponse result = scalekitClient.tokens().validate(token);
// Attach token context for downstream handlers
request.setAttribute("tokenInfo", result.getTokenInfo());
filterChain.doFilter(request, response);
} catch (TokenInvalidException e) {
// Revoked, expired, or malformed tokens are rejected immediately
response.sendError(401, "Invalid or expired token");
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required security comment pattern in middleware examples.

Security-related code must include the standard comment string. Please add it in each language example near token validation.

✏️ Example (Node.js)
   try {
+    // Security: ALWAYS verify requests are from Scalekit before processing
     // Server-side validation — Scalekit checks token status in real time
     const result = await scalekit.token.validateToken(token);

As per coding guidelines: “Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'.”

🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 725 - 875, Add
the required security comment string "// Security: ALWAYS verify requests are
from Scalekit before processing" immediately adjacent to the token validation
call in each example: in the Express middleware function authenticateToken
(where scalekit.token.validateToken is called), in the Flask decorator
authenticate_token (where scalekit_client.tokens.validate_token is called), in
the Gin handler AuthenticateToken (around scalekitClient.Token().ValidateToken),
and in the Spring Boot filter TokenAuthFilter.doFilterInternal (around
scalekitClient.tokens().validate); place the comment right above or on the same
line as the validation call so it is clearly associated with the security check.

…ters for Go optional proto fields, add missing Token import in Java middleware
… error handling to list/invalidate examples across all languages
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea6e0d8 and 7808ce7.

📒 Files selected for processing (1)
  • src/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.mdx

📄 CodeRabbit inference engine (.cursorrules)

**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component: 1. ## Title with all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)

**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/deno-docs-style.mdc)

**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and purposeful - annotate only what matters
Use consistent variable and file names across a documentation page
Use descriptive link text in documentation (e.g., 'See permission flags' not 'click here')
Prefer relative links for internal documentation pages and include anchors for section references
Reference APIs consistently using backticks for code, file names, CLI flags, and endpoints
Use backticks for code, file names, CLI flags, and endpoints in documentation
Use lists for options and features in documentation; tables only when comparisons are cleare...

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (28)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Keep documentation accurate and up-to-date with product changes, updating examples when APIs change
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use sentence case for headings near code examples (e.g., 'Authenticate users')

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Use SDK variable names: Node.js `scalekit`, Python `scalekit_client`, Go `scalekitClient`, Java `scalekitClient`

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Ensure code examples reflect current APIs and are tested when possible

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include error handling in code examples showing both success and error paths

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Include security comments in code examples explaining threats and security implications

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Prefer comments explaining intent in code examples, not restating code

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Line 898: Add the required STYLE-CHECK footer after the final paragraph in the
documentation: append a single line "STYLE-CHECK: TODO" (or "STYLE-CHECK:
PASSED" if ready) at the end of the content in the api-keys.mdx document so the
file ends with that line; locate the end of the final paragraph in the current
content (the line "You now have everything you need to issue, validate, and
manage API keys in your application.") and add the STYLE-CHECK line immediately
after it.
- Around line 27-45: Wrap the existing d2 sequence diagram fenced block (the
```d2 pad=36 ... ``` block) in a collapsible details section: place a <details>
tag above and a </details> tag below, add a <summary> line containing an icon
and short label (e.g., "✏️ Sequence diagram" or similar) and keep the original
fenced diagram content unchanged inside the collapsible; ensure
indentation/whitespace remains valid for MDX so the diagram renders when the
section is expanded.
- Around line 117-197: The headings "Organization-scoped API key" and
"User-scoped API key" are noun phrases—change them to action-oriented headings
(e.g., "Create an organization-scoped API key" and "Create a user-scoped API
key" or "Generate an organization-scoped API key" / "Generate a user-scoped API
key") to follow the guideline "Use action verbs in section headings"; update
both heading lines and any internal links or table-of-contents references that
point to those headings so they remain consistent.
- Around line 60-107: Update all SDK initialization snippets (ScalekitClient,
scalekitClient, scalekit_client, NewScalekitClient) to include brief inline
comments showing where each credential/config value comes from (e.g., "Get the
environment URL and client credentials from your Scalekit dashboard >
Interceptors/Environment settings" or "Set these as environment variables:
SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET"); place
the comments immediately above or on the same line as the constructor call in
the Node (ScalekitClient), Python (ScalekitClient), Go (NewScalekitClient) and
Java (ScalekitClient) examples so readers can see the source of each value
without guessing.
- Around line 674-713: Add explicit success and error handling to each token
invalidation example: wrap
scalekit.token.invalidateToken(opaqueToken)/scalekit.token.invalidateToken(tokenId)
in a try/catch (or promise .then/.catch) and log success vs error; for Python
wrap scalekit_client.tokens.invalidate_token(...) in try/except and handle
exceptions/print success; for Go check the returned err from
scalekitClient.Token().InvalidateToken(ctx, ...) and handle/log success or
error; for Java surround scalekitClient.tokens().invalidate(...) with try/catch
(or check thrown exceptions) and log success or failure. Ensure each snippet
shows both the success path and the error/logging path using the same
function/method names shown.
- Around line 303-542: Multiple validation snippets call token validation
without the required security comment; add the standardized comment "//
Security: ALWAYS verify requests are from Scalekit before processing"
immediately above each call to validateToken / scalekit.token.validateToken
(Node.js), scalekit_client.tokens.validate_token (Python),
scalekitClient.Token().ValidateToken (Go), and scalekitClient.tokens().validate
(Java) in the validation, roles, and custom-metadata code blocks so every
security-related validation call includes the mandated comment.
- Around line 124-283: Add a one-line "Use case" comment and a one-line "Next
step/TODO" comment to every create-token example shown (Node.js:
scalekit.token.createToken and scalekit.token.createToken for user-scoped;
Python: scalekit_client.tokens.create_token; Go:
scalekitClient.Token().CreateToken; Java: scalekitClient.tokens().create),
placing the comments immediately above the call and immediately after storing
the returned token respectively; ensure the use-case describes the scenario
(e.g., "Use case: CI/CD pipeline token" or "Use case: per-user deployment
token") and the next-step/TODO indicates what to do with the token (e.g., "TODO:
store token securely; next guide covers session creation").
- Around line 18-68: Add an import for Code from `@astrojs/starlight/components`
below the frontmatter and replace the fenced JS snippet inside the TabItem (the
block that shows ScalekitClient/Express.js) with a <Code> component usage: move
the snippet source into the code prop, set lang="javascript", title="Express.js"
and convert collapse={1-2} into the collapse prop format accepted by <Code>.
Keep the TabItem and surrounding Tabs intact and ensure other fenced blocks with
title/collapse in this file are similarly converted.

---

Duplicate comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 21-23: The opening paragraph uses inconsistent casing ("API keys"
vs "API Keys"), long sentences, and some subject–verb agreement issues; revise
the first block (the paragraph starting "When your customers need to
integrate...") to use consistent "API keys" casing, break long sentences into
shorter ones (<25 words each), fix subject–verb agreement (e.g., ensure verbs
match singular/plural subjects), and simplify phrasing for clarity—keep that the
keys are long-lived, revocable bearer credentials scoped to organization or
user, cannot be validated client-side, must be validated server-side by
Scalekit, and that revocation is immediate; update the subsequent sentence about
claims and scoping similarly for brevity and plain language.
- Around line 725-875: Insert the required security comment "// Security: ALWAYS
verify requests are from Scalekit before processing" immediately adjacent to the
server-side validation call in each middleware example: in the Node.js
authenticateToken function add the comment right before the
scalekit.token.validateToken(token) call; in the Flask authenticate_token
decorator add it just before scalekit_client.tokens.validate_token(...); in the
Go AuthenticateToken handler add it before
scalekitClient.Token().ValidateToken(...); and in the Java
TokenAuthFilter.doFilterInternal method add it immediately before
scalekitClient.tokens().validate(token). Ensure the comment text matches the
required pattern exactly and sits on its own line for each validation call.
- Around line 551-662: Update each language example to include explicit success
and error handling and replace restating comments with intent-focused comments:
for Node.js update usages of scalekit.token.listTokens to handle both resolved
response and caught errors (e.g., try/catch or .then/.catch) and change comments
to explain intent like "fetch first page of tokens for org" and "fetch next page
if present"; for Python update scalekit_client.tokens.list_tokens to check
responses and catch exceptions (try/except) and use intent comments; for Go
update scalekitClient.Token().ListTokens calls to check and handle returned err
values and verify nextPage token before calling again, and use intent comments;
for Java update scalekitClient.tokens().list usages to handle exceptions or
check outcome and document intent rather than restating code. Ensure each
snippet shows both the success path (processing response.tokens) and an error
path (logging or handling the error).
- Around line 1-6: Update the frontmatter of this MDX to include a numeric order
field, enable the table of contents by adding tableOfContents: true, and change
the sidebar label from "Add API Keys" to sentence case "Add API keys"; ensure
title and description meet length guidelines (title ≤60 chars, description ≤160
chars) and keep tags unchanged.
- Around line 891-897: Convert the four bullet tips into CheckItem components
(use the existing CheckItem MDX pattern) so each best-practice becomes a
separate <CheckItem> entry, and replace the plain list with that component-based
checklist; additionally add a short inline example or a one-line code snippet
showing how to set the expiry parameter when creating a key (use the
repository's API method that accepts expiry, referenced as expiry) or add a link
to the relevant API docs, ensuring the example uses the current expiry parameter
name and mirrors other CheckItem usages in the docs.

Comment on lines +18 to +68
import { Aside, Steps, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
import InstallSDK from '@components/templates/_installsdk.mdx';

When your customers need to integrate with your APIs — whether for CI/CD pipelines, partner integrations, or internal tooling — they need a straightforward way to authenticate. Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs.

Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented. Revocation of API keys takes effect immediately with no expiry windows or propagation delays. Each key is scoped to an organization and optionally to a specific user, making it easy to build personal access tokens, per-user rate limiting, and audit trails.

In this guide, you'll learn how to create, validate, list, and revoke API keys using the Scalekit SDK.

```d2 pad=36
shape: sequence_diagram

API Client
User
Your App
Scalekit

User -> Your App: Request API key
Your App -> Scalekit: Create token (organizationId, userId)
Scalekit -> Your App: API key + tokenId
Your App -> User: API key
User -> API Client: Configure API key
API Client -> Your App: Request with Authorization header
Your App -> Scalekit: Validate token
Scalekit -> Your App: Organization, user, and role info
Your App -> Your App: Process request
Your App -> API Client: Response
```

<Aside type="tip">
The plain-text API key is returned **only at creation time**. Scalekit does not store the key and cannot retrieve it later. Instruct your users to copy and store the key securely before closing the creation dialog.
</Aside>

## Install the SDK

<InstallSDK />

Initialize the Scalekit client with your environment credentials:

<Tabs syncKey="tech-stack">
<TabItem value="node" label="Node.js">

```javascript title="Express.js" collapse={1-2}
import { ScalekitClient } from '@scalekit-sdk/node';

const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find examples of <Code> usage with title and collapse properties
echo "=== <Code> components with title prop ==="
rg -A 3 '<Code[^>]*title=' src/content/docs -g "*.mdx" | head -40

echo ""
echo "=== <Code> components with collapse prop ==="
rg -A 3 '<Code[^>]*collapse=' src/content/docs -g "*.mdx" | head -40

echo ""
echo "=== Full import statements with Code ==="
rg "import.*Code.*from.*starlight" src/content/docs -g "*.mdx" | head -10

Repository: scalekit-inc/developer-docs

Length of output: 1811


🏁 Script executed:

#!/bin/bash
# Find files with Code imports and show their actual usage
echo "=== Files with Code import ==="
rg "import.*Code.*from.*starlight" src/content/docs -g "*.mdx" -l | head -3

echo ""
echo "=== Actual <Code> component usage in first file ==="
rg '<Code' src/content/docs/reference/agent-connectors/zoom.mdx -A 5 | head -40

echo ""
echo "=== Check another file ==="
rg '<Code' src/content/docs/reference/agent-connectors/fathom.mdx -A 5 | head -40

Repository: scalekit-inc/developer-docs

Length of output: 349


🏁 Script executed:

#!/bin/bash
# More comprehensive search for Code component usage
echo "=== Search for <Code usage across entire docs ==="
find src/content/docs -name "*.mdx" -exec grep -l "<Code" {} \; 2>/dev/null | head -5

echo ""
echo "=== Check the actual content of files that use Code ==="
find src/content/docs -name "*.mdx" -exec grep -l "<Code" {} \; 2>/dev/null | head -1 | xargs cat | head -100

echo ""
echo "=== Search for fenced code blocks with title attribute ==="
rg '```\w+\s+title=' src/content/docs -g "*.mdx" | head -10

echo ""
echo "=== Current file content around code block ==="
sed -n '45,58p' src/content/docs/authenticate/m2m/api-keys.mdx

Repository: scalekit-inc/developer-docs

Length of output: 1620


🏁 Script executed:

#!/bin/bash
# Check one of the files using fenced code with title/collapse
echo "=== Check sso/quickstart.mdx import statement ==="
head -5 src/content/docs/sso/quickstart.mdx

echo ""
echo "=== Check if it imports Code ==="
rg "import.*Code" src/content/docs/sso/quickstart.mdx

echo ""
echo "=== Show a code block example from that file ==="
sed -n '95,105p' src/content/docs/sso/quickstart.mdx

echo ""
echo "=== Check api-keys.mdx import ==="
head -5 src/content/docs/authenticate/m2m/api-keys.mdx

Repository: scalekit-inc/developer-docs

Length of output: 1152


🏁 Script executed:

#!/bin/bash
# Check for Expressive Code configuration or documentation in the repo
echo "=== Look for expressive-code config ==="
find . -name "*expressive*" -o -name "astro.config*" | head -10

echo ""
echo "=== Check astro.config for expressive code ==="
rg "expressive" . --type js --type ts 2>/dev/null | head -20

echo ""
echo "=== Check package.json for expressive-code ==="
rg "expressive" package.json

echo ""
echo "=== Look at the actual fenced syntax being used ==="
sed -n '48,54p' src/content/docs/authenticate/m2m/api-keys.mdx
</parameter>

Repository: scalekit-inc/developer-docs

Length of output: 820


🏁 Script executed:

#!/bin/bash
# Read the expressive-code rule file
echo "=== Content of expressive-code.mdc ==="
cat .cursor/rules/expressive-code.mdc

echo ""
echo "=== Check the actual code block in api-keys.mdx ==="
sed -n '48,55p' src/content/docs/authenticate/m2m/api-keys.mdx

Repository: scalekit-inc/developer-docs

Length of output: 3408


Import Code from @astrojs/starlight/components and convert fenced code blocks with title and collapse attributes to use the <Code> component.

The code block at lines 48–54 uses a fenced syntax with title="Express.js" and collapse={1-2}, but per the Expressive Code guidelines, snippets with titles should use Starlight's <Code> component instead. Add the import below the frontmatter and refactor the snippet to use <Code code={...} lang="javascript" title="Express.js" collapse={...} /> (or similar structure for other code blocks in this file).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 18 - 68, Add an
import for Code from `@astrojs/starlight/components` below the frontmatter and
replace the fenced JS snippet inside the TabItem (the block that shows
ScalekitClient/Express.js) with a <Code> component usage: move the snippet
source into the code prop, set lang="javascript", title="Express.js" and convert
collapse={1-2} into the collapse prop format accepted by <Code>. Keep the
TabItem and surrounding Tabs intact and ensure other fenced blocks with
title/collapse in this file are similarly converted.

Comment on lines +27 to +45
```d2 pad=36
shape: sequence_diagram

API Client
User
Your App
Scalekit

User -> Your App: Request API key
Your App -> Scalekit: Create token (organizationId, userId)
Scalekit -> Your App: API key + tokenId
Your App -> User: API key
User -> API Client: Configure API key
API Client -> Your App: Request with Authorization header
Your App -> Scalekit: Validate token
Scalekit -> Your App: Organization, user, and role info
Your App -> Your App: Process request
Your App -> API Client: Response
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Place the sequence diagram in a collapsible section.

Diagrams in the introduction should be collapsible with an icon.

✏️ Suggested wrapper
+<details>
+  <summary>🧭 API key lifecycle</summary>
+  ...
+</details>

As per coding guidelines: "Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 27 - 45, Wrap
the existing d2 sequence diagram fenced block (the ```d2 pad=36 ... ``` block)
in a collapsible details section: place a <details> tag above and a </details>
tag below, add a <summary> line containing an icon and short label (e.g., "✏️
Sequence diagram" or similar) and keep the original fenced diagram content
unchanged inside the collapsible; ensure indentation/whitespace remains valid
for MDX so the diagram renders when the section is expanded.

Comment on lines +60 to +107
```javascript title="Express.js" collapse={1-2}
import { ScalekitClient } from '@scalekit-sdk/node';

const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);
```

</TabItem>
<TabItem value="python" label="Python">

```python title="Flask" collapse={1-2}
import os
from scalekit import ScalekitClient

scalekit_client = ScalekitClient(
env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"],
client_id=os.environ["SCALEKIT_CLIENT_ID"],
client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)
```

</TabItem>
<TabItem value="go" label="Go">

```go title="Gin" collapse={1-2}
import scalekit "github.com/scalekit-inc/scalekit-sdk-go/v2"

scalekitClient := scalekit.NewScalekitClient(
os.Getenv("SCALEKIT_ENVIRONMENT_URL"),
os.Getenv("SCALEKIT_CLIENT_ID"),
os.Getenv("SCALEKIT_CLIENT_SECRET"),
)
```

</TabItem>
<TabItem value="java" label="Java">

```java title="Spring Boot" collapse={1-2}
import com.scalekit.ScalekitClient;

ScalekitClient scalekitClient = new ScalekitClient(
System.getenv("SCALEKIT_ENVIRONMENT_URL"),
System.getenv("SCALEKIT_CLIENT_ID"),
System.getenv("SCALEKIT_CLIENT_SECRET")
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add configuration context comments in SDK initialization snippets.

Call out where the credentials come from so readers don’t need to guess.

✏️ Example (Node.js)
-const scalekit = new ScalekitClient(
+// Get the environment URL, client ID, and secret from the Scalekit dashboard
+const scalekit = new ScalekitClient(
   process.env.SCALEKIT_ENVIRONMENT_URL,
   process.env.SCALEKIT_CLIENT_ID,
   process.env.SCALEKIT_CLIENT_SECRET
 );

As per coding guidelines: "Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 60 - 107, Update
all SDK initialization snippets (ScalekitClient, scalekitClient,
scalekit_client, NewScalekitClient) to include brief inline comments showing
where each credential/config value comes from (e.g., "Get the environment URL
and client credentials from your Scalekit dashboard > Interceptors/Environment
settings" or "Set these as environment variables: SCALEKIT_ENVIRONMENT_URL,
SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET"); place the comments immediately
above or on the same line as the constructor call in the Node (ScalekitClient),
Python (ScalekitClient), Go (NewScalekitClient) and Java (ScalekitClient)
examples so readers can see the source of each value without guessing.

Comment on lines +117 to +197
### Organization-scoped API key

Create an API key scoped to an organization. This is the most common pattern for service-to-service integrations where the API key represents access on behalf of an entire organization.

<Tabs syncKey="tech-stack">
<TabItem value="node" label="Node.js">

```javascript
try {
const response = await scalekit.token.createToken(organizationId, {
description: 'CI/CD pipeline token',
});

// Store securely — this value cannot be retrieved again after creation
const opaqueToken = response.token;
// Stable identifier for management operations (format: apit_xxxxx)
const tokenId = response.tokenId;
} catch (error) {
console.error('Failed to create token:', error.message);
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
try:
response = scalekit_client.tokens.create_token(
organization_id=organization_id,
description="CI/CD pipeline token",
)

# SDK returns (response, metadata) tuple — access response at index 0
opaque_token = response[0].token # store this securely
token_id = response[0].token_id # format: apit_xxxxx
except Exception as e:
print(f"Failed to create token: {e}")
```

</TabItem>
<TabItem value="go" label="Go">

```go
response, err := scalekitClient.Token().CreateToken(
ctx, organizationId, scalekit.CreateTokenOptions{
Description: "CI/CD pipeline token",
},
)
if err != nil {
log.Printf("Failed to create token: %v", err)
return
}

// Store securely — this value cannot be retrieved again after creation
opaqueToken := response.Token
// Stable identifier for management operations (format: apit_xxxxx)
tokenId := response.TokenId
```

</TabItem>
<TabItem value="java" label="Java">

```java
try {
CreateTokenResponse response = scalekitClient.tokens().create(organizationId);

// Store securely — this value cannot be retrieved again after creation
String opaqueToken = response.getToken();
// Stable identifier for management operations (format: apit_xxxxx)
String tokenId = response.getTokenId();
} catch (Exception e) {
System.err.println("Failed to create token: " + e.getMessage());
}
```

</TabItem>
</Tabs>

### User-scoped API key

Scope an API key to a specific user within an organization to enable personal access tokens, per-user audit trails, and user-level rate limiting. You can also attach custom claims as key-value metadata.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Make scope headings action‑oriented.

These headings are noun phrases; convert them to action verbs.

✏️ Suggested headings
-### Organization-scoped API key
+### Create an organization-scoped API key
...
-### User-scoped API key
+### Create a user-scoped API key

As per coding guidelines: "Use action verbs in section headings".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 117 - 197, The
headings "Organization-scoped API key" and "User-scoped API key" are noun
phrases—change them to action-oriented headings (e.g., "Create an
organization-scoped API key" and "Create a user-scoped API key" or "Generate an
organization-scoped API key" / "Generate a user-scoped API key") to follow the
guideline "Use action verbs in section headings"; update both heading lines and
any internal links or table-of-contents references that point to those headings
so they remain consistent.

Comment on lines +124 to +283
```javascript
try {
const response = await scalekit.token.createToken(organizationId, {
description: 'CI/CD pipeline token',
});

// Store securely — this value cannot be retrieved again after creation
const opaqueToken = response.token;
// Stable identifier for management operations (format: apit_xxxxx)
const tokenId = response.tokenId;
} catch (error) {
console.error('Failed to create token:', error.message);
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
try:
response = scalekit_client.tokens.create_token(
organization_id=organization_id,
description="CI/CD pipeline token",
)

# SDK returns (response, metadata) tuple — access response at index 0
opaque_token = response[0].token # store this securely
token_id = response[0].token_id # format: apit_xxxxx
except Exception as e:
print(f"Failed to create token: {e}")
```

</TabItem>
<TabItem value="go" label="Go">

```go
response, err := scalekitClient.Token().CreateToken(
ctx, organizationId, scalekit.CreateTokenOptions{
Description: "CI/CD pipeline token",
},
)
if err != nil {
log.Printf("Failed to create token: %v", err)
return
}

// Store securely — this value cannot be retrieved again after creation
opaqueToken := response.Token
// Stable identifier for management operations (format: apit_xxxxx)
tokenId := response.TokenId
```

</TabItem>
<TabItem value="java" label="Java">

```java
try {
CreateTokenResponse response = scalekitClient.tokens().create(organizationId);

// Store securely — this value cannot be retrieved again after creation
String opaqueToken = response.getToken();
// Stable identifier for management operations (format: apit_xxxxx)
String tokenId = response.getTokenId();
} catch (Exception e) {
System.err.println("Failed to create token: " + e.getMessage());
}
```

</TabItem>
</Tabs>

### User-scoped API key

Scope an API key to a specific user within an organization to enable personal access tokens, per-user audit trails, and user-level rate limiting. You can also attach custom claims as key-value metadata.

<Tabs syncKey="tech-stack">
<TabItem value="node" label="Node.js">

```javascript
try {
const userToken = await scalekit.token.createToken(organizationId, {
userId: 'usr_12345',
customClaims: {
team: 'engineering',
environment: 'production',
},
description: 'Deployment service token',
});

const opaqueToken = userToken.token;
const tokenId = userToken.tokenId;
} catch (error) {
console.error('Failed to create token:', error.message);
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
try:
user_token = scalekit_client.tokens.create_token(
organization_id=organization_id,
user_id="usr_12345",
custom_claims={
"team": "engineering",
"environment": "production",
},
description="Deployment service token",
)

opaque_token = user_token[0].token
token_id = user_token[0].token_id
except Exception as e:
print(f"Failed to create token: {e}")
```

</TabItem>
<TabItem value="go" label="Go">

```go
userToken, err := scalekitClient.Token().CreateToken(
ctx, organizationId, scalekit.CreateTokenOptions{
UserId: "usr_12345",
CustomClaims: map[string]string{
"team": "engineering",
"environment": "production",
},
Description: "Deployment service token",
},
)
if err != nil {
log.Printf("Failed to create user token: %v", err)
return
}

opaqueToken := userToken.Token
tokenId := userToken.TokenId
```

</TabItem>
<TabItem value="java" label="Java">

```java
try {
Map<String, String> customClaims = Map.of(
"team", "engineering",
"environment", "production"
);

CreateTokenResponse userToken = scalekitClient.tokens().create(
organizationId, "usr_12345", customClaims, null, "Deployment service token"
);

String opaqueToken = userToken.getToken();
String tokenId = userToken.getTokenId();
} catch (Exception e) {
System.err.println("Failed to create token: " + e.getMessage());
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add required use‑case and next‑step comments to create‑token snippets.

Each code example should include a use‑case comment and a next‑step/TODO comment.

✏️ Example (Node.js)
 try {
+  // Use case: Issue a CI/CD token for automated deployments
   const response = await scalekit.token.createToken(organizationId, {
     description: 'CI/CD pipeline token',
   });
   ...
   const tokenId = response.tokenId;
+  // Next step: Store tokenId and show the key once to the user
 } catch (error) {

As per coding guidelines: "Include use case comments explaining scenarios in code examples: '// Use case: Provision a workspace after a sales-assisted onboarding'" and "Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 124 - 283, Add a
one-line "Use case" comment and a one-line "Next step/TODO" comment to every
create-token example shown (Node.js: scalekit.token.createToken and
scalekit.token.createToken for user-scoped; Python:
scalekit_client.tokens.create_token; Go: scalekitClient.Token().CreateToken;
Java: scalekitClient.tokens().create), placing the comments immediately above
the call and immediately after storing the returned token respectively; ensure
the use-case describes the scenario (e.g., "Use case: CI/CD pipeline token" or
"Use case: per-user deployment token") and the next-step/TODO indicates what to
do with the token (e.g., "TODO: store token securely; next guide covers session
creation").

Comment on lines +303 to +542
```javascript
import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node';

try {
const result = await scalekit.token.validateToken(opaqueToken);

const orgId = result.tokenInfo?.organizationId;
const userId = result.tokenInfo?.userId;
const claims = result.tokenInfo?.customClaims;
} catch (error) {
if (error instanceof ScalekitValidateTokenFailureException) {
// Token is invalid, expired, or revoked
console.error('Token validation failed:', error.message);
}
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
from scalekit import ScalekitValidateTokenFailureException

try:
result = scalekit_client.tokens.validate_token(token=opaque_token)

org_id = result[0].token_info.organization_id
user_id = result[0].token_info.user_id
claims = result[0].token_info.custom_claims
except ScalekitValidateTokenFailureException:
# Token is invalid, expired, or revoked
print("Token validation failed")
```

</TabItem>
<TabItem value="go" label="Go">

```go
result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken)
if errors.Is(err, scalekit.ErrTokenValidationFailed) {
// Token is invalid, expired, or revoked
log.Printf("Token validation failed: %v", err)
return
}

orgId := result.TokenInfo.OrganizationId
userId := result.TokenInfo.GetUserId() // *string — nil for org-scoped tokens
claims := result.TokenInfo.CustomClaims
```

</TabItem>
<TabItem value="java" label="Java">

```java
import com.scalekit.exceptions.TokenInvalidException;

try {
ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken);

String orgId = result.getTokenInfo().getOrganizationId();
String userId = result.getTokenInfo().getUserId();
Map<String, String> claims = result.getTokenInfo().getCustomClaimsMap();
} catch (TokenInvalidException e) {
// Token is invalid, expired, or revoked
System.err.println("Token validation failed: " + e.getMessage());
}
```

</TabItem>
</Tabs>

If the API key is invalid, expired, or has been revoked, validation fails with a specific error that you can catch and handle in your code. This makes it easy to reject unauthorized requests in your API middleware.

### Access roles and organization details

Beyond the basic organization and user information, the validation response also includes any roles assigned to the user and external identifiers you've configured for the organization. These are useful for making authorization decisions without additional database lookups.

<Tabs syncKey="tech-stack">
<TabItem value="node" label="Node.js">

```javascript
try {
const result = await scalekit.token.validateToken(opaqueToken);

// Roles assigned to the user
const roles = result.tokenInfo?.roles;

// External identifiers for mapping to your system
const externalOrgId = result.tokenInfo?.organizationExternalId;
const externalUserId = result.tokenInfo?.userExternalId;
} catch (error) {
if (error instanceof ScalekitValidateTokenFailureException) {
console.error('Token validation failed:', error.message);
}
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
try:
result = scalekit_client.tokens.validate_token(token=opaque_token)

# Roles assigned to the user
roles = result[0].token_info.roles

# External identifiers for mapping to your system
external_org_id = result[0].token_info.organization_external_id
external_user_id = result[0].token_info.user_external_id
except ScalekitValidateTokenFailureException:
print("Token validation failed")
```

</TabItem>
<TabItem value="go" label="Go">

```go
result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken)
if errors.Is(err, scalekit.ErrTokenValidationFailed) {
log.Printf("Token validation failed: %v", err)
return
}

// Roles assigned to the user
roles := result.TokenInfo.Roles

// External identifiers for mapping to your system
externalOrgId := result.TokenInfo.OrganizationExternalId
externalUserId := result.TokenInfo.GetUserExternalId() // *string — nil if no external ID
```

</TabItem>
<TabItem value="java" label="Java">

```java
try {
ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken);

// Roles assigned to the user
List<String> roles = result.getTokenInfo().getRolesList();

// External identifiers for mapping to your system
String externalOrgId = result.getTokenInfo().getOrganizationExternalId();
String externalUserId = result.getTokenInfo().getUserExternalId();
} catch (TokenInvalidException e) {
System.err.println("Token validation failed: " + e.getMessage());
}
```

</TabItem>
</Tabs>

<Aside type="note">
Roles are available when you use [Full Stack Authentication](/authenticate/fsa/quickstart/) with [role-based access control](/authenticate/authz/overview/). Assign roles to users through the Scalekit dashboard or API.
</Aside>

### Access custom metadata

If you attached custom claims when creating the API key, they come back in every validation response. This is a convenient way to make fine-grained authorization decisions — like restricting access by team or environment — without hitting your database.

<Tabs syncKey="tech-stack">
<TabItem value="node" label="Node.js">

```javascript
try {
const result = await scalekit.token.validateToken(opaqueToken);

const team = result.tokenInfo?.customClaims?.team;
const environment = result.tokenInfo?.customClaims?.environment;

// Use metadata for authorization
if (environment !== 'production') {
return res.status(403).json({ error: 'Production access required' });
}
} catch (error) {
if (error instanceof ScalekitValidateTokenFailureException) {
console.error('Token validation failed:', error.message);
}
}
```

</TabItem>
<TabItem value="python" label="Python">

```python
try:
result = scalekit_client.tokens.validate_token(token=opaque_token)

team = result[0].token_info.custom_claims.get("team")
environment = result[0].token_info.custom_claims.get("environment")

# Use metadata for authorization
if environment != "production":
return jsonify({"error": "Production access required"}), 403
except ScalekitValidateTokenFailureException:
print("Token validation failed")
```

</TabItem>
<TabItem value="go" label="Go">

```go
result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken)
if errors.Is(err, scalekit.ErrTokenValidationFailed) {
log.Printf("Token validation failed: %v", err)
return
}

team := result.TokenInfo.CustomClaims["team"]
environment := result.TokenInfo.CustomClaims["environment"]

// Use metadata for authorization
if environment != "production" {
c.JSON(403, gin.H{"error": "Production access required"})
return
}
```

</TabItem>
<TabItem value="java" label="Java">

```java
try {
ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken);

String team = result.getTokenInfo().getCustomClaimsMap().get("team");
String environment = result.getTokenInfo().getCustomClaimsMap().get("environment");

// Use metadata for authorization
if (!"production".equals(environment)) {
return ResponseEntity.status(403).body(Map.of("error", "Production access required"));
}
} catch (TokenInvalidException e) {
System.err.println("Token validation failed: " + e.getMessage());
}
```

</TabItem>
</Tabs>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Insert the standard security comment before each validation call.

Add the required security comment near each validateToken call in the validation, roles, and custom-metadata snippets.

✏️ Example (Node.js)
 try {
+  // Security: ALWAYS verify requests are from Scalekit before processing
   const result = await scalekit.token.validateToken(opaqueToken);

As per coding guidelines: "Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 303 - 542,
Multiple validation snippets call token validation without the required security
comment; add the standardized comment "// Security: ALWAYS verify requests are
from Scalekit before processing" immediately above each call to validateToken /
scalekit.token.validateToken (Node.js), scalekit_client.tokens.validate_token
(Python), scalekitClient.Token().ValidateToken (Go), and
scalekitClient.tokens().validate (Java) in the validation, roles, and
custom-metadata code blocks so every security-related validation call includes
the mandated comment.

- **Use custom claims for context**: Attach metadata like `team`, `environment`, or `service` as custom claims. Your API middleware can use these claims for fine-grained authorization without additional database lookups.
- **Rotate keys safely**: To rotate an API key, create a new key, update the consuming service to use the new key, verify the new key works, then invalidate the old key. This avoids downtime during rotation.

You now have everything you need to issue, validate, and manage API keys in your application. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required STYLE-CHECK line at the end.

Include a STYLE-CHECK: TODO (or PASSED) line after the final paragraph.

✏️ Suggested footer
-You now have everything you need to issue, validate, and manage API keys in your application. 
+You now have everything you need to issue, validate, and manage API keys in your application.
+STYLE-CHECK: TODO

As per coding guidelines: "Include a STYLE-CHECK: [PASSED | TODO] line at the end of every documentation draft".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` at line 898, Add the required
STYLE-CHECK footer after the final paragraph in the documentation: append a
single line "STYLE-CHECK: TODO" (or "STYLE-CHECK: PASSED" if ready) at the end
of the content in the api-keys.mdx document so the file ends with that line;
locate the end of the final paragraph in the current content (the line "You now
have everything you need to issue, validate, and manage API keys in your
application.") and add the STYLE-CHECK line immediately after it.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7808ce7 and 3e056ac.

📒 Files selected for processing (1)
  • src/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.mdx

📄 CodeRabbit inference engine (.cursorrules)

**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component: 1. ## Title with all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)

**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (.cursor/rules/deno-docs-style.mdc)

**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and purposeful - annotate only what matters
Use consistent variable and file names across a documentation page
Use descriptive link text in documentation (e.g., 'See permission flags' not 'click here')
Prefer relative links for internal documentation pages and include anchors for section references
Reference APIs consistently using backticks for code, file names, CLI flags, and endpoints
Use backticks for code, file names, CLI flags, and endpoints in documentation
Use lists for options and features in documentation; tables only when comparisons are cleare...

Files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (47)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Keep documentation accurate and up-to-date with product changes, updating examples when APIs change
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use sentence case for headings near code examples (e.g., 'Authenticate users')

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Use SDK variable names: Node.js `scalekit`, Python `scalekit_client`, Go `scalekitClient`, Java `scalekitClient`

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Ensure code examples reflect current APIs and are tested when possible

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include error handling in code examples showing both success and error paths

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Include security comments in code examples explaining threats and security implications

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Prefer comments explaining intent in code examples, not restating code

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use Expressive Code consistently across all documentation pages, preferring Starlight's `<Code>` component for rich features (titles, markers, accurate syntax highlighting) and dynamic snippets over fenced code blocks

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Import `{ Code }` from `astrojs/starlight/components` once per `.mdx` file, placing the import below frontmatter

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Prefer `<Code>` component when code snippets need any of: filename/title, text markers, programmatic/dynamic content, or consistent theming across tabs

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code collapsible sections plugin must be enabled in `astro.config.mjs`

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Provide a `title` prop to the `<Code>` component when the snippet represents a file

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use 'collapse={lines}' to hide imports, setup, and boilerplate code in code blocks

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use 'title' attribute in code blocks to show framework names: 'Express.js', 'Flask', 'Gin', 'Spring Boot'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Keep code examples minimal and runnable; avoid extraneous comments and explain intent above or below the block instead of inline

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Use diagrams when they improve understanding; keep them simple

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include use case comments explaining scenarios in code examples: '// Use case: Provision a workspace after a sales-assisted onboarding'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should be action-oriented - start with verbs when possible

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Use active voice and imperative mood for steps and procedures in documentation

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action-oriented headings in step-by-step guides within Steps components

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Show both success and error paths in code examples

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.

Applied to files:

  • src/content/docs/authenticate/m2m/api-keys.mdx
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 674-697: The Java listing lacks error handling: wrap calls to
scalekitClient.tokens().list (the initial call, the paginated call using
response.getNextPageToken(), and the filtered call that returns userTokens) in a
try/catch block that catches Exception (or a more specific client exception),
print a clear error message and exception details (e.g., System.err.println or
logging with e.printStackTrace()) in the catch, and keep the existing
success-path code that iterates over ListTokensResponse and Token inside the try
block so both success and error paths are shown.

---

Duplicate comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 791-793: The middleware examples call scalekit.token.validateToken
but are missing the required standardized security comment; add the prescribed
security comment block immediately above each validateToken invocation in the
Node.js example (near scalekit.token.validateToken), and likewise add the same
comment in the Python, Go, and Java middleware examples where validateToken (or
equivalent token validation call) is used so the security rationale and audit
info are present for each validation site.
- Around line 1-16: The frontmatter is missing tableOfContents and the sidebar
label uses Title Case; add a top-level frontmatter key tableOfContents: true and
change the sidebar label value from "Add API Keys" to sentence-case "Add API
keys" (update the 'tableOfContents' frontmatter entry and the 'sidebar: label'
field in this file so the page renders a TOC and follows the sentence-case
guideline).
- Around line 124-137: Add concise use-case and next-step/TODO comments around
the token creation snippet: before scalekit.token.createToken include a one-line
comment describing when to use a CI/CD pipeline token (e.g., automated
deployment or CI jobs), and after extracting opaqueToken and tokenId add
comments stating that opaqueToken must be stored securely (cannot be retrieved
later) and tokenId is for management operations; also add a TODO comment
suggesting rotating the token, storing it in a secret manager, and linking to
the equivalent examples for Python, Go, Java and the user-scoped token snippets
so readers know next steps and where to find language-specific variants.
- Around line 179-193: The Java example omits the description parameter when
calling scalekitClient.tokens().create; update the call to include a description
string (matching Node/Python/Go examples) so the created token has a
human-readable description. Edit the snippet around
scalekitClient.tokens().create(organizationId) in the method that returns
CreateTokenResponse so it passes the description argument, and leave the
subsequent uses of response.getToken() and response.getTokenId() unchanged.
- Line 117: Change the noun headings "Organization-scoped API key" and
"User-scoped API key" to action-oriented headings that start with a verb (e.g.,
"Create organization-scoped API key" and "Create user-scoped API key") so the
token creation sections follow the action-oriented heading guideline; update
both heading occurrences ("Organization-scoped API key" and "User-scoped API
key") in the document.
- Around line 308-323: Add the required security comment immediately above the
token validation call(s) to follow the security comment pattern; specifically
insert the standard comment before scalekit.token.validateToken(opaqueToken) in
this Node.js snippet and mirror the same comment placement for the other
language examples (Python/Go/Java) referenced, so that each validation call is
preceded by the security annotation; keep exception handling using
ScalekitValidateTokenFailureException and existing variables (opaqueToken,
result.tokenInfo) unchanged, only add the comment line(s) in front of the
validateToken invocation.
- Around line 60-68: Replace the fenced JavaScript block with the <Code>
component from `@astrojs/starlight/components` to support title/collapse metadata:
import the Code component and wrap the ScalekitClient example using <Code
language="javascript" title="Express.js" collapse={true}> containing the same
code that constructs ScalekitClient (refer to the ScalekitClient constructor
call and the three process.env args) so the snippet renders with the preferred
component and preserves title/collapse behavior.
- Around line 27-45: Wrap the existing sequence diagram code block (the fenced
block containing "d2 pad=36" and "shape: sequence_diagram") in a collapsible
HTML details element: add a <details> with a <summary> that includes the
suggested icon (e.g., "✏️ Suggested wrapper") above the opening triple-backtick
and close the details after the closing triple-backtick, preserving the exact
diagram content and fence markers so rendering is unchanged when expanded.
- Line 958: This doc ending after the sentence "You now have everything you need
to issue, validate, and manage API keys in your application." is missing the
required STYLE-CHECK footer; append a single line at the end of the file reading
"STYLE-CHECK: [PASSED | TODO]" (choose PASSED if style checks are complete,
otherwise TODO) so the document conforms to the STYLE-CHECK requirement.
- Around line 57-68: Add brief configuration-context comments above each
SDK/client initialization so readers know where credentials come from and how to
set them: in the Node snippet add comments above the ScalekitClient
instantiation (and the scalekit const) explaining that
process.env.SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and
SCALEKIT_CLIENT_SECRET are environment variables populated from the Scalekit
dashboard or CI secrets; do the same for the equivalent client/class
instantiations in the Python, Go, and Java examples, mentioning how to obtain
the credentials and recommended storage (env vars or secrets manager).
- Around line 21-23: Update the opening paragraphs to fix grammar and
consistency: change "gives you" to "give you", replace "Organizational or User
Level" with "organization- or user-level", normalize "API Keys" to "API keys",
and hyphenate "client side" to "client-side"; ensure the sentence using "API
keys" and "client-side" reads smoothly after these replacements and keep
lowercase/Hyphenation consistent across the paragraph when referring to API keys
and client-side validation.
- Line 954: The "Set expiry for time-limited access" best-practice references an
expiry parameter but lacks an example; add a short code snippet under that
bullet showing how to pass the expiry when creating an API key (e.g., call to
createApiKey / POST /v1/api-keys with an expiry field using an ISO-8601
timestamp or TTL seconds) and/or add a link to the API reference for
createApiKey so readers can see parameter details; update the line containing
"Set expiry for time-limited access" and the `expiry` mention to include this
example or the reference link.

Comment on lines +674 to +697

```java
import com.scalekit.grpc.scalekit.v1.tokens.ListTokensResponse;
import com.scalekit.grpc.scalekit.v1.tokens.Token;

// List tokens for an organization
ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null);

for (Token token : response.getTokensList()) {
System.out.println(token.getTokenId() + " " + token.getDescription());
}

// Paginate through results
if (!response.getNextPageToken().isEmpty()) {
ListTokensResponse nextPage = scalekitClient.tokens().list(
organizationId, 10, response.getNextPageToken()
);
}

// Filter tokens by user
ListTokensResponse userTokens = scalekitClient.tokens().list(
organizationId, "usr_12345", 10, null
);
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add error handling to Java list tokens example.

The Node.js, Python, and Go examples include error handling, but the Java example lacks a try/catch block. Per coding guidelines, all code examples should show both success and error paths.

✏️ Suggested fix
+try {
     // List tokens for an organization
     ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null);

     for (Token token : response.getTokensList()) {
         System.out.println(token.getTokenId() + " " + token.getDescription());
     }

     // Paginate through results
     if (!response.getNextPageToken().isEmpty()) {
         ListTokensResponse nextPage = scalekitClient.tokens().list(
             organizationId, 10, response.getNextPageToken()
         );
     }

     // Filter tokens by user
     ListTokensResponse userTokens = scalekitClient.tokens().list(
         organizationId, "usr_12345", 10, null
     );
+} catch (Exception e) {
+    System.err.println("Failed to list tokens: " + e.getMessage());
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 674 - 697, The
Java listing lacks error handling: wrap calls to scalekitClient.tokens().list
(the initial call, the paginated call using response.getNextPageToken(), and the
filtered call that returns userTokens) in a try/catch block that catches
Exception (or a more specific client exception), print a clear error message and
exception details (e.g., System.err.println or logging with e.printStackTrace())
in the catch, and keep the existing success-path code that iterates over
ListTokensResponse and Token inside the try block so both success and error
paths are shown.

Python SDK's token.py dropped .with_call so methods now return plain
proto response objects instead of (response, call) tuples. Update all
Python code examples in the API keys guide to remove [0] indexing.
@hrishikesh-p hrishikesh-p deleted the feature/opaque-tokens-docs branch February 24, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants